package com.ruoyi.data.vo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

@Data
public class ResultData<T> {
  public static final int SUCCESS_CODE = 200;
  private int code = 200;
  private String msg;
  private T data;

  public static <T> ResultData<T> okOf() {
    ResultData<T> resultData = new ResultData<>();
    resultData.setCode(SUCCESS_CODE);
    resultData.setMsg("ok");
    return resultData;
  }

  public static <T> ResultData<T> okOf(String message) {
    ResultData<T> resultData = new ResultData<>();
    resultData.setCode(SUCCESS_CODE);
    resultData.setMsg(message);
    return resultData;
  }

  public static <T> ResultData<T> okOf(int code, String message) {
    ResultData<T> resultData = new ResultData<>();
    resultData.setMsg(message);
    resultData.setCode(code);
    return resultData;
  }

  public static <T> ResultData<T> resultOf(T t) {
    ResultData<T> resultData = new ResultData<>();
    resultData.setCode(SUCCESS_CODE);
    resultData.setMsg("ok");
    resultData.setData(t);
    return resultData;
  }

  public static <T> ResultData<T> errorOf(int code, String message) {
    return buildErrorData(code, message);
  }

  public static <T> ResultData<T> errorOf(int code, String message, Object... args) {
    return buildErrorData(code, message, args);
  }

  public static <T> ResultData<T> buildErrorData(int code, String message, Object... args) {
    ResultData<T> resultData = new ResultData<>();
    resultData.setCode(code);
    if (StringUtils.isNotEmpty(message)) {
      message = MessageFormat.format(message, args);
    }

    resultData.setMsg(message);
    return resultData;
  }

  @JsonIgnore
  public boolean getSuccess() {
    return this.code == 200;
  }

  @JsonIgnore
  public Map<String, Object> getMap() {
    Map<String, Object> map = new HashMap<>(3);
    map.put("code", this.code);
    map.put("msg", this.msg);
    map.put("data", this.data);
    return map;
  }
}
